package com.dkd.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dkd.dao.OrderCollectDao;
import com.dkd.entity.OrderCollectEntity;
import com.dkd.entity.vo.BarCharCollect;
import com.dkd.service.OrderCollectService;
import com.dkd.vo.Pager;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class OrderCollectServiceImpl extends ServiceImpl<OrderCollectDao, OrderCollectEntity> implements OrderCollectService {
    private final RestHighLevelClient esClient;
    private final OrderCollectDao orderCollectDao;

    @Override
    public BarCharCollect getCollect(Integer partnerId, LocalDate start, LocalDate end) {
        List<OrderCollectEntity>  orderCollectEntities=orderCollectDao.getCollect(partnerId,start,end);
        var qw = new QueryWrapper<OrderCollectEntity>();
        qw.select(" IFNULL( sum(total_bill),0) as total_bill", "date")
                .lambda()
                .ge(OrderCollectEntity::getDate, start)
                .le(OrderCollectEntity::getDate, end)
                .eq(OrderCollectEntity::getOwnerId, partnerId)
                .groupBy(OrderCollectEntity::getDate);

        var mapCollect = this.list(qw).stream()
                .collect(Collectors.toMap(OrderCollectEntity::getDate, OrderCollectEntity::getTotalBill));

        var result = new BarCharCollect();

        start.datesUntil(end.plusDays(1), Period.ofDays(1))
                .forEach(date -> {
                    result.getXAxis().add(date.format(DateTimeFormatter.ISO_LOCAL_DATE));
                    if (mapCollect.containsKey(date)) {
                        result.getSeries().add(mapCollect.get(date));
                    } else {
                        result.getSeries().add(0);
                    }
                });
        return result;
    }

    @Override
    public Pager<OrderCollectEntity> getPartnerCollect(Long pageIndex, Long pageSize, Integer partnerId, LocalDate start, LocalDate end) {
        Page<OrderCollectEntity> page = new Page<>(pageIndex, pageSize);
        this.lambdaQuery().like(partnerId != null, OrderCollectEntity::getOwnerId, partnerId)
                .between(OrderCollectEntity::getDate, start, end).page(page);

        return Pager.build(page);
    }

    @Override
    public BarCharCollect getAmountCollect(Integer collectType, LocalDate start, LocalDate end) {

        var groupColumn = collectType == 2 ? "MONTH(date)" : "date";

        var dateColumn = collectType == 2 ? "min(date) as date" : "date";

        var formatter = collectType == 2 ? DateTimeFormatter.ofPattern("yyyy-MM") : DateTimeFormatter.ISO_LOCAL_DATE;

        var period = collectType == 2 ? Period.ofMonths(1) : Period.ofDays(1);

        var qw = new QueryWrapper<OrderCollectEntity>();

        qw.select("IFNULL(sum(order_total_money),0) as order_total_money", dateColumn)
                .groupBy(groupColumn)
                .lambda()
                .ge(OrderCollectEntity::getDate, start)
                .le(OrderCollectEntity::getDate, end)
                .orderByAsc(OrderCollectEntity::getDate);

        var mapCollect = this.list(qw)
                .stream().collect(Collectors.toMap(o -> o.getDate().format(formatter), OrderCollectEntity::getOrderTotalMoney));
        var result = new BarCharCollect();

        start.datesUntil(end.plusDays(1), period)
                .forEach(date -> {
                    String key = date.format(formatter);
                    result.getXAxis().add(key);
                    if (mapCollect.containsKey(key)) {
                        result.getSeries().add(mapCollect.get(key));
                    } else {
                        result.getSeries().add(0);
                    }
                });
        return result;
    }



    @Override
    public List<OrderCollectEntity> getTop12(Integer partnerId) {

        return this.lambdaQuery().eq(OrderCollectEntity::getOwnerId, partnerId).orderByDesc(OrderCollectEntity::getDate)
                .list().stream().limit(12).collect(Collectors.toList());
    }

    @Override
    public BarCharCollect getCollectByRegion(LocalDate start, LocalDate end) {

        return null;
    }



}
